package com.czy.ekp.util;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@Slf4j
public class FileUtils {


    public static boolean isValid(String fileName){
        //不允许出现的特殊字符  / \ " : | * ? < > .
        return  fileName.matches("[^\\s\\\\/:\\*\\?\\\"<>\\|](\\x20|[^\\s\\\\/:\\*\\?\\\"<>\\|])*[^\\s\\\\/:\\*\\?\\\"<>\\|\\.]$");
    }

    public static boolean download(String srcFilePath, HttpServletResponse response, String destFileName){
        BufferedInputStream ins = null;
        BufferedOutputStream bos = null;
        try {
            ins = new BufferedInputStream(new FileInputStream(srcFilePath));
            byte[] out = new byte[ins.available()];
            ins.read(out);
            // 清空response
            response.reset();
            // 将输出流写出到servlet
            response.setContentLength(out.length);
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(destFileName));
            bos = new BufferedOutputStream(response.getOutputStream());
            bos.write(out);
            // 刷新servlet输出流
            bos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (ins != null) {
                try {
                    ins.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    /**
     * 获取文件名后缀（eg: .png）
     * @param fileName
     * @return
     */
    public static String fileSuffix(String fileName){
        return fileName.substring(fileName.lastIndexOf("."));
    }

    public static byte[] requestBytes(HttpServletRequest request) {
        byte mStream[] = null;
        int totalRead = 0;
        int readBytes = 0;
        int totalBytes = 0;
        try {
            totalBytes = request.getContentLength();
            mStream = new byte[totalBytes];
            while (totalRead < totalBytes) {
                request.getInputStream();
                readBytes = request.getInputStream().read(mStream, totalRead,
                        totalBytes - totalRead);
                totalRead += readBytes;
                continue;
            }
        }
        catch (Exception e) {
            System.out.println(e.toString());
        }
        return (mStream);
    }

    public static String absoluteStaticPath(String relativePath) throws FileNotFoundException {
        File path = new File(ResourceUtils.getURL("classpath:").getPath());
        if(!path.exists()){
            path = new File("");
        }

        File upload = new File(path.getAbsolutePath(),"static" + relativePath);
        if(!upload.exists()){
            upload.mkdirs();
        }
        log.info("upload url:"+upload.getAbsolutePath());
        return upload.getAbsolutePath();
    }

    public static ResultMap fileUpload(String destDir, String downloadUrl, MultipartFile file){
        ResultMap result = ResultMap.success();
        try{
            Random rd = new Random();
            String suffix  = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            String dstFileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + "_" + rd.nextInt(1000) + suffix;
            File dest = new File(absoluteStaticPath(destDir) + File.separator +dstFileName);
            file.transferTo(dest);
            result.put("url", downloadUrl + dstFileName);
            result.put("title", file.getOriginalFilename());
            result.put("size", dest.getTotalSpace());
        }catch (Exception e){
            e.printStackTrace();
            result.put("message", "上传出错:" + e.getMessage());
        }
        return result;
    }

    public static boolean fileDownload(String destDir, String file, OutputStream os){
        FileInputStream fis = null;
        try{
            fis = new FileInputStream(absoluteStaticPath(destDir) + File.separator + file);
            IOUtils.copy(fis, os);
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }


    public static boolean zip(List<InputStream> isList, List<String> nameList, OutputStream os){

        try {
            ZipOutputStream zos = new ZipOutputStream(os);
            byte[] buffer = new byte[2048];
            int len;
            for(int i=0; i<isList.size(); i++){

                InputStream is = isList.get(i);
                if(is == null || is.available() <= 0){
                    return false;
                }

                zos.putNextEntry(new ZipEntry(nameList.get(i)));

                while ((len = is.read(buffer)) != -1) {
                    zos.write(buffer, 0, len);
                }

                zos.closeEntry();
                is.close();
            }
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

        return true;
    }

    public static boolean unZip(InputStream is, Map<String, OutputStream> osMap){

        try{
            ZipInputStream zis = new ZipInputStream(is);
            byte[] buffer = new byte[2048];
            int len;
            ZipEntry entry;
            while((entry = zis.getNextEntry()) != null){
                OutputStream os = osMap.get(entry.getName());
                if(os != null){
                    while ((len = zis.read(buffer)) != -1) {
                        os.write(buffer, 0, len);
                    }
                }
                zis.closeEntry();
                os.close();
            }

            zis.close();
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }


        return true;
    }


    public static void main(String args[]){
        System.out.println(fileSuffix("1111.png"));
    }

}
